﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once
#include "GcmpModelInterface.h"
namespace gcmp
{
    class IDocument;

    /// \brief 按需加载
    class GCMP_MODEL_INTERFACE_EXPORT ICollaborationLoadOnDemandManager
    {
    public:
        /// \brief 按需加载
        /// 
        /// \param pDocument当前文档
        /// \param elementIds 需要加载的ElementIds
        /// \param excludeDependencies 是否加载强弱依赖关系，true表示不加载，false表示加载
        /// \return
        virtual void LoadOnDemand(IDocument* pDocument, const std::vector<ElementId>& elementIds, bool excludeDependencies) = 0;

        /// \brief 对象是否可卸载选项
        /// 
        /// 比如，在Dataset A中参照了来自Dataset B的对象X，对象X可能被其它对象Y依赖。
        /// 判断X是否可以卸载：
        ///     如果Y属于A，可以卸载；
        ///     如果Y属于B，可以卸载；
        ///     如果Y属于C，根据此选项，决定X是否可以被卸载。
        enum class UnloadOptionIfThereAreDescendantOf3rdDataset : int32_t
        {
            ForceUnloadEvenIfThereAreDirectWeakDescendantsOf3rdDataset = 1 << 0,    /// < 即使有来自第三方工作单元的弱后代依赖这个对象，也可以卸载
            ForceUnloadEvenIfThereAreDirectStrongDescendantsOf3rdDataset = 1 << 1,  /// < 即使有来自第三方工作单元的强后代依赖这个对象，也可以卸载
        };

        /// \brief 查找可以被卸载的对象
        /// 
        /// \param pDocument当前文档
        /// \param datasetId 需要卸载的目标工作单元。不能是当期文档的主工作单元。
        /// \param option 组合选项值，来自UnloadOptionIfThereAreDescendantOf3rdDataset
        /// \return 可以被卸载的对象
        static std::set<ElementId> CanUnload(
            IDocument* pDocument,
            const std::wstring & datasetId,
            int32_t options
        );

        /// \brief 卸载对象
        /// 
        /// \param pDocument当前文档
        /// \param unloadable 可以被卸载的对象Id，从CanUnload()计算出
        /// \param pErrorMessage 错误消息。传入非空、有错误时，传出
        /// \return 卸载结果
        static bool Unload(
            IDocument * pDocument,
            const std::set<ElementId> & unloadable,
            std::wstring * pErrorMessage
        );

        /// \析构函数
        virtual ~ICollaborationLoadOnDemandManager();
    };
}
